package com.sunmnet.auto.spring.mvc;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import com.sunmnet.pub.db.exception.NoConfException;
import com.sunmnet.util.lang.StringUtils;

public class Utils {
	
    /**
     * 使用getBeanFromDB或getBeanFromPDM时，
     * 若需要删除表名前缀的规范部分（如"T_","T_ZHWG_"等），可把该前缀配置到这里。
     * 移除前缀有先后，首先匹配到的前缀先移除，其后的前缀不再执行移除
     */
    public static List<String> removeTablePres = new LinkedList<String>();
    


	/**
	 * 检查每列
	 *
	 * @param dmd
	 *            DatabaseMetaData对象
	 * @param tblName
	 *            表名
	 * @return ResultSet集合
	 * @throws SQLException
	 *             获取不到数据名
	 */
	public static ResultSet checkColumnsType(DatabaseMetaData dmd,
			String tblName) throws SQLException {
		String dbName = dmd.getDatabaseProductName();
		ResultSet tabs = null;

		if (dbName.toLowerCase().equals("oracle")) {
			tabs = dmd.getColumns(null, dmd.getUserName().toUpperCase(),
					tblName, null);
		} else if (dbName.toLowerCase().equals("mysql")) {
			tabs = dmd.getColumns(null, "%", tblName, "%");
		} else if (dbName.equals("Adaptive Server Enterprise")) {
			tabs = dmd.getColumns(null, null, tblName, null);
		}
		return tabs;
	}



	/**
	 * 数据库的数据类型转换java 数据类型
	 *
	 * @param source
	 *            数据库的数据类型
	 * @return java 数据类型
	 */
	public static String dataBaseToJavaType(String source) {
		String result = null;
		source = source.toLowerCase();
		
		if (source.equals("float")) {
			result = "float";
		} else if (source.contains("varchar") || source.startsWith("char")
				|| source.startsWith("varchar2") || source.startsWith("long")
				|| source.contains("longtext") || source.startsWith("text")
				|| "enum".equals(source)) {
			result = "String";
		} else if (source.contains("smallint")
				|| source.equals("mediumint") || source.equals("tinyint")) {
			result = "Short";
		} else if (source.startsWith("number")|| source.startsWith("numeric")
				||source.startsWith("int")
				||source.startsWith("bigint")) {
			result = "Long";
		} else if (source.contains("timestamp")) {
			result = "java.util.Date";
		} else if (source.equals("date")) {
			result = "java.util.Date";
		} else if (source.equals("time")) {
			result = "java.sql.Time";
		} else if (source.contains("datetime") || source.equals("timestamp")) {
			result = "Date";
		} else if (source.contains("double")) {
			result = "Double";
		} else if (source.contains("decimal")) {
			result = "Double";
		} else if (source.equals("blob")) {
			result = "blob";
		} else if ("clob".equals(source)) {
			result = "clob";
		}
		
		if (checkNotNull(result)) {
			return result;
		} else {
			throw new NoConfException("后台暂不支持该数据库类型转换成对应的java数据类型:" + source);
		}
	}
	
    /**
     * 判断字符串是否为空
     *
     * @param param
     *            传入的字符串
     * @return true：不空，false：空
     */
    public static boolean checkNotNull(String param) {
        boolean bool = true;

        if (param == null || "".equals(param.trim())) {
            bool = false;
        } else {
            return bool;
        }
        return bool;
    }
    
	/**
	 * 判断数据库类型
	 *
	 * @param dmd
	 *            DatabaseMetaData对象
	 * @return ResultSet ResultSet对象
	 * @throws SQLException
	 *             获取不到数据库类型
	 */
	public static ResultSet checkDBType(DatabaseMetaData dmd)
			throws SQLException {
		String types[] = { "TABLE" };
		String dbName = dmd.getDatabaseProductName();
		ResultSet tabs = null;

		if (dbName.toLowerCase().equals("oracle")) {
			tabs = dmd.getTables(null, dmd.getUserName().toUpperCase(), null,
					types);
		} else if (dbName.toLowerCase().equals("mysql")) {
			tabs = dmd.getTables(null, null, null, types);
		} else if (dbName.equals("Adaptive Server Enterprise")) {
			tabs = dmd.getTables(null, null, null, types);
		} else if (dbName.toLowerCase().equals("sqlserver")) {
			tabs = dmd.getTables(null, null, null, types);
		}
		return tabs;
	} 
    
	/**
	 * 把字符串数组转换为列表
	 * 
	 * @param strArray
	 *            字符串数组
	 * @return 若入参为null则返回null
	 */
	public static List<String> strArray2List(String[] strArray) {
		List<String> tnArr = new ArrayList<String>();
		for(int i=0; i< strArray.length; i++){
			tnArr.add(strArray[i].trim());
		}
		return tnArr;
	}    
    
    
    /**
     * 转换字符串的第一个字母为小写
     *
     * @param str 要转换字符串
     * @return 转换后的结果 ，如： String==>string
     */
    public static String firstWordToLow(String str) {
        String first = str.substring(0, 1);
        String suffix = str.substring(1, str.length());
        return first.toLowerCase() + suffix;
    }
    /**
     * 转换字符串的第一个字母大写
     *
     * @param str 要转换字符串
     * @return 转换后的结果 ，如： string==>String
     */
    public static String firstWordToUpp(String str) {
        String first = str.substring(0, 1);
        String suffix = str.substring(1, str.length());
        return first.toUpperCase() + suffix;
    }
    
	/**
	 * 把含下划线的表名构造为驼峰结构，并剔除诸如以"T_ZHWG_"或"T_"开头的规范部分(需配置,默认不剔除).
	 * 不带下划线的表名,剔除前缀并将首字母大写后返回.
	 * 
	 * 若处理完得到的名称是java关键字，则前面补 $
	 * 
	 * @param tableName 原表名
	 * @param tablePreList 希望移除表名开头的规范部分内容。可传入多个判定式，但仅匹配第1个
	 * @return 若表名不含下划线则原样返回；否则返回驼峰结构的表名
	 */
	public static String getHumpTableName(
			String tableName, List<String> tablePreList) {
		String tmpName = tableName;
		
		//含下划线的表名
		if(tmpName != null && tmpName.contains("_")) {
			StringBuffer sb = new StringBuffer();
			
			//若表名以下划线开头，剔除之
			while(tmpName.startsWith("_")) {
				tmpName = tmpName.substring(1);
			}
			
			//若表名以下划线结尾，剔除之，防止下面操作数组越界
			while(tmpName.endsWith("_")) {
				tmpName = tmpName.substring(0, tmpName.length() - 1);
			}
			
			//剔除表名开头的规范部分
			for(String str : tablePreList) {
				if(tmpName.startsWith(str)) {
					tmpName = tmpName.substring(str.length());
					break;
				}
			}
			
			//若表名以下划线开头，剔除之
			while(tmpName.startsWith("_")) {
				tmpName = tmpName.substring(1);
			}
			
			tmpName = tmpName.toLowerCase();
			char[] charArray = tmpName.toCharArray();
			sb.append((char) (charArray[0] - 32));	//表名首字母大写
			
			//把下划线删除，其后的字母转为大写
			for(int i = 1; i < charArray.length; i++) {
				if(charArray[i] == '_') {
					i++;
					sb.append((char) (charArray[i] - 32));
				} else {
					sb.append(charArray[i]);
				}
			}
			tmpName = sb.toString();
			
		//不含下划线的表名
		} else {
			
			//剔除表名开头的规范部分
			for(String str : tablePreList) {
				if(tmpName.startsWith(str)) {
					tmpName = tmpName.substring(str.length());
					break;
				}
			}
			
			//首字母大写
			tmpName = firstWordToUpp(tmpName);
		}
		
		if(true == isJavaKeyWord(tmpName)) {
			tmpName = "$" + tmpName;
		}
		return tmpName;
	}
	/**
	 * java关键数组
	 */
	private final static String[] JAVA_KEY_WORDS = { "abstract", "assert",
			"boolean", "break", "byte", "case", "catch", "char", "class",
			"const", "continue", "default", "do", "double", "else", "enum",
			"extends", "final", "finally", "float", "for", "goto", "if",
			"implements", "import", "instanceof", "int", "interface", "long",
			"native", "new", "package", "private", "protected", "public",
			"return", "short", "static", "strictfp", "super", "switch",
			"synchronized", "this", "throw", "throws", "transient", "try",
			"void", "volatile", "while", };

	/**
	 * java关键字列表
	 */
	private final static List<String> JAVA_KEY_WORD_LIST = strArray2List(JAVA_KEY_WORDS);

	
	/**
	 * 检查字符串是否为java关键字
	 *
	 * @param str
	 *            待检查字符串
	 * @return true:是 ; false:不是
	 */
	private static boolean isJavaKeyWord(String str) {
		boolean isKeyWord = false;
		if (str != null && !"".equals(str.trim())) {
			isKeyWord = JAVA_KEY_WORD_LIST.contains(str.trim());
		}
		return isKeyWord;
	}
    
    
	/**
	 * 把含下划线的列名构造为驼峰结构.
	 * 不带下划线的列名则只改变首字母大小写.
	 * 
	 * 若处理完得到的名称是java关键字，则前面补 _
	 * 
	 * @param columnName 列名
	 * @param firstUpper 开头字母是否需要大写
	 * @return 驼峰形式列名
	 */
	public static String getHumpColumnName(
			String columnName, boolean firstUpper) {
		String tmpName = columnName;
		
		//含下划线的列名
		if(tmpName != null && tmpName.contains("_")) {
			StringBuilder sb = new StringBuilder();
			
			//若列名以下划开头，剔除之
			while(tmpName.startsWith("_")) {
				tmpName = tmpName.substring(1);
			}
			
			//删除字段类型前缀 I_ 、 S_ 、D_ 等
			if(tmpName.charAt(1) == '_') {
				tmpName = tmpName.substring(2);
			}
			
			//若列名以下划结尾，剔除之，防止下面操作数组越界
			while(tmpName.endsWith("_")) {
				tmpName = tmpName.substring(0, tmpName.length() - 1);
			}
			
			tmpName = tmpName.toLowerCase();
			char[] charArray = tmpName.toCharArray();
			
			//首字母大写
			if(firstUpper == true) {
				sb.append((char) (charArray[0] - 32));
				
			//首字母小写
			} else {
				sb.append(charArray[0]);	
			}
			
			//把下划线删除，其后的字母转为大写
			for(int i = 1; i < charArray.length; i++) {
				if(charArray[i] == '_') {
					i++;
					sb.append((char) (charArray[i] - 32));
				} else {
					sb.append(charArray[i]);
				}
			}
			tmpName = sb.toString();
			
		//不含下划线的列名
		} else {
			if(firstUpper == true) {
				tmpName = firstWordToUpp(tmpName);
			} else {
				tmpName = firstWordToLow(tmpName);
			}
		}
		
		if(true == isJavaKeyWord(tmpName)) {
			tmpName = "_" + tmpName;
		}
		return tmpName;
	}
    
    /**
     * 
     *
     * @param name
     * @return
     */
	public static String lowerFristWord(String name) {
		return name.substring(0, 1).toLowerCase() + name.substring(1);
	}



	public static String charLength(String source, String length) {
		source = source.toLowerCase();

		if (source.startsWith("varchar") 
				|| source.startsWith("char")
				|| source.startsWith("varchar2") 
				|| source.startsWith("long")
				|| source.startsWith("longtext") 
				|| source.startsWith("text")
				|| "enum".equals(source)) {
			if (StringUtils.isNotEmpty(length)) {
				int len = Integer.parseInt(length) / 2;
				length = len + "";
			}
		}
		return length;
	}    
}
